/***************************************************************************
 创建者: 华磊
 开始时间: 2019.4.12
 copyright: (C) 华友高科
 修改说明: (每次有修改就添加一条，带有 修改人，修改时间，修改描述)
 example (1) hualei 2020.5.8 类的具体实现代码编写
 ***************************************************************************/
#include "encoderreceiver.h"
#include "domparser.h"
#include <QDebug>


EncoderReceiver::EncoderReceiver(E_DEVICE_PROTOCOL protocolIn, int aliasIn, QString configFileIn)
{
    isInitialOk=false;
    alias=aliasIn;
    pdoData.doOutput=0;

    pdoData.Encoder0_Val=0;
    pdoData.Encoder1_Val=0;
    pdoData.Encoder2_Val=0;
    pdoData.Encoder0_Val_count=0;
    pdoData.Encoder1_Val_count=0;
    pdoData.Encoder2_Val_count=0;
    pdoData.Encoder0_Val_old=0;
    pdoData.Encoder1_Val_old=0;
    pdoData.Encoder2_Val_old=0;

    pdoData.Ltc0_Encoder0Val=0;
    pdoData.Ltc0_Encoder1Val=0;
    pdoData.Ltc0_Encoder2Val=0;
    pdoData.Ltc0_Encoder0Val_count=0;
    pdoData.Ltc0_Encoder1Val_count=0;
    pdoData.Ltc0_Encoder2Val_count=0;
    pdoData.Ltc0_Encoder0Val_old=0;
    pdoData.Ltc0_Encoder1Val_old=0;
    pdoData.Ltc0_Encoder2Val_old=0;

    pdoData.Ltc1_Encoder0Val=0;
    pdoData.Ltc1_Encoder1Val=0;
    pdoData.Ltc1_Encoder2Val=0;
    pdoData.Ltc1_Encoder0Val_count=0;
    pdoData.Ltc1_Encoder1Val_count=0;
    pdoData.Ltc1_Encoder2Val_count=0;
    pdoData.Ltc1_Encoder0Val_old=0;
    pdoData.Ltc1_Encoder1Val_old=0;
    pdoData.Ltc1_Encoder2Val_old=0;

    pdoData.Ltc2_Encoder0Val=0;
    pdoData.Ltc2_Encoder1Val=0;
    pdoData.Ltc2_Encoder2Val=0;
    pdoData.Ltc2_Encoder0Val_count=0;
    pdoData.Ltc2_Encoder1Val_count=0;
    pdoData.Ltc2_Encoder2Val_count=0;
    pdoData.Ltc2_Encoder0Val_old=0;
    pdoData.Ltc2_Encoder1Val_old=0;
    pdoData.Ltc2_Encoder2Val_old=0;

    pdoData.Ltc3_Encoder0Val=0;
    pdoData.Ltc3_Encoder1Val=0;
    pdoData.Ltc3_Encoder2Val=0;
    pdoData.Ltc3_Encoder0Val_count=0;
    pdoData.Ltc3_Encoder1Val_count=0;
    pdoData.Ltc3_Encoder2Val_count=0;
    pdoData.Ltc3_Encoder0Val_old=0;
    pdoData.Ltc3_Encoder1Val_old=0;
    pdoData.Ltc3_Encoder2Val_old=0;

    if(1==readConfigFile(configFileIn))
    {
        isInitialOk=true;
    }
}

int EncoderReceiver::getEncoderReceiverOutput(unsigned short &doOut)
{
    doOut=pdoData.doOutput;
    return 1;
}

int EncoderReceiver::setEncoderReceiverOutput(unsigned short doIn)
{
//    qDebug()<<"EncoderReceiver::setEncoderReceiverOutput"<<doIn;
    pdoData.doOutput=doIn;
    return 1;
}

/*a是寄存器，b是要操作的位*/
#define BIT_SET(a,b) ((a) |= (1<<(b)))              //置位
#define BIT_CLEAR(a,b) ((a) &= ~(1<<(b)))    //清除位
#define BIT_FLIP(a,b) ((a) ^= (1<<(b)))           //位翻转

int EncoderReceiver::setEncoderReceiverOutput_bit(int bitIndex, bool isHigh)
{
    if(isHigh)
    {
        BIT_SET(pdoData.doOutput,bitIndex);
    }
    else
    {
        BIT_CLEAR(pdoData.doOutput,bitIndex);
    }
    return 1;
}

int EncoderReceiver::getEncoderReceiverData(EncoderReceiverData &dataOut)
{
    dataOut=pdoData;
    dataOut.deviceAlias=alias;
    return 1;
}

int EncoderReceiver::setVendorId(int vendorIdIn)
{
    vendorId=vendorIdIn;
    return 1;
}

bool EncoderReceiver::isInitialOkStatus()
{
    return isInitialOk;
}

int EncoderReceiver::checkMultiVerse()
{/*
    translateIntToLonglong(pdoData.Encoder0_Val,pdoData.Encoder0_Val_old,pdoData.Encoder0_Val_count,pdoData.Encoder0_Val_longlong);
    translateIntToLonglong(pdoData.Encoder1_Val,pdoData.Encoder1_Val_old,pdoData.Encoder1_Val_count,pdoData.Encoder1_Val_longlong);
    translateIntToLonglong(pdoData.Encoder2_Val,pdoData.Encoder2_Val_old,pdoData.Encoder2_Val_count,pdoData.Encoder2_Val_longlong);

    translateIntToLonglong(pdoData.Ltc0_Encoder0Val,pdoData.Ltc0_Encoder0Val_old,pdoData.Ltc0_Encoder0Val_count,
                           pdoData.Ltc0_Encoder0Val_longlong);
    translateIntToLonglong(pdoData.Ltc0_Encoder1Val,pdoData.Ltc0_Encoder1Val_old,pdoData.Ltc0_Encoder1Val_count,
                           pdoData.Ltc0_Encoder1Val_longlong);
    translateIntToLonglong(pdoData.Ltc0_Encoder2Val,pdoData.Ltc0_Encoder2Val_old,pdoData.Ltc0_Encoder2Val_count,
                           pdoData.Ltc0_Encoder2Val_longlong);

    translateIntToLonglong(pdoData.Ltc1_Encoder0Val,pdoData.Ltc1_Encoder0Val_old,pdoData.Ltc1_Encoder0Val_count,
                           pdoData.Ltc1_Encoder0Val_longlong);
    translateIntToLonglong(pdoData.Ltc1_Encoder1Val,pdoData.Ltc1_Encoder1Val_old,pdoData.Ltc1_Encoder1Val_count,
                           pdoData.Ltc1_Encoder1Val_longlong);
    translateIntToLonglong(pdoData.Ltc1_Encoder2Val,pdoData.Ltc1_Encoder2Val_old,pdoData.Ltc1_Encoder2Val_count,
                           pdoData.Ltc1_Encoder2Val_longlong);

    translateIntToLonglong(pdoData.Ltc2_Encoder0Val,pdoData.Ltc2_Encoder0Val_old,pdoData.Ltc2_Encoder0Val_count,
                           pdoData.Ltc2_Encoder0Val_longlong);
    translateIntToLonglong(pdoData.Ltc2_Encoder1Val,pdoData.Ltc2_Encoder1Val_old,pdoData.Ltc2_Encoder1Val_count,
                           pdoData.Ltc2_Encoder1Val_longlong);
    translateIntToLonglong(pdoData.Ltc2_Encoder2Val,pdoData.Ltc2_Encoder2Val_old,pdoData.Ltc2_Encoder2Val_count,
                           pdoData.Ltc2_Encoder2Val_longlong);

    translateIntToLonglong(pdoData.Ltc3_Encoder0Val,pdoData.Ltc3_Encoder0Val_old,pdoData.Ltc3_Encoder0Val_count,
                           pdoData.Ltc3_Encoder0Val_longlong);
    translateIntToLonglong(pdoData.Ltc3_Encoder1Val,pdoData.Ltc3_Encoder1Val_old,pdoData.Ltc3_Encoder1Val_count,
                           pdoData.Ltc3_Encoder1Val_longlong);
    translateIntToLonglong(pdoData.Ltc3_Encoder2Val,pdoData.Ltc3_Encoder2Val_old,pdoData.Ltc3_Encoder2Val_count,
                           pdoData.Ltc3_Encoder2Val_longlong);*/
}

int EncoderReceiver::readConfigFile(  QString filepath )
{

    DomParser domparser;
    bool ok=domparser.openXml(filepath, QFile::ReadOnly|QFile::Text );
    if(!ok)
    {
        qDebug()<<"error,,,EncoderReceiver::readConfigFile :"<<ok<< filepath;
        return -1;
    }

    QDomNode domNode = domparser.findSubNode(domparser.getRootDomElement(), "sdoSetting", ok );
    if( !ok )
    {
            qDebug() << " 读取结点失败：" << filepath;
            return -1;
    }

    QDomNodeList devNodes = domNode.childNodes();
    int ncount=devNodes.size();

    SdoConfig tmpSdoConfig;
    for(int i=0;i<ncount;i++)
    {
        QDomNode devND =  devNodes.at(i);
        if( devND.nodeName().indexOf("#comment")>=0){
            continue;
        }

        bool isSucess;
        tmpSdoConfig.index=  devND.toElement().attribute("index" ).toUInt(&isSucess,16);
        tmpSdoConfig.subindex=  devND.toElement().attribute("subindex" ).toUInt(&isSucess,16);
        tmpSdoConfig.byteLength=  devND.toElement().attribute("byteLength" ).toUInt(&isSucess,16);
        tmpSdoConfig.value=  devND.toElement().attribute("value" ).toUInt(&isSucess,16);
        sdoConfigList.append(tmpSdoConfig);

    }

    domparser.closeXml();


    return 1;
}

#define D_2POW30 1073741824
#define D_2POW32 4294967296

int EncoderReceiver::translateIntToLonglong(const int &valueNewIn, int &valueOldIn, int &count, long long &valueOut)
{
    //允许编码器每次最大变化量2^30
    if(valueNewIn-valueOldIn>D_2POW30)
    {
        count--;
    }
    else if(valueNewIn-valueOldIn<-D_2POW30)
    {
        count++;
    }
    else
    {

    }
    valueOut=count*D_2POW32+valueNewIn;
    valueOldIn=valueNewIn;
    return 1;
}
